﻿Imports System
Imports System.Collections
Imports System.Globalization
Imports System.Reflection
Imports System.Runtime.InteropServices

Namespace System.Workflow.ComponentModel.Compiler
    Friend Class ParseHelpers
        ' Methods
        Friend Shared Function AssemblyNameEquals(ByVal thisName As AssemblyName, ByVal thatName As AssemblyName) As Boolean
            Dim buffer As Byte()
            If ((thisName.Name Is Nothing) OrElse (thatName.Name Is Nothing)) Then
                Return False
            End If
            If Not thatName.Name.Equals(thisName.Name) Then
                Return False
            End If
            Dim version As Version = thatName.Version
            If (((Not version Is Nothing) AndAlso (Not version Is ParseHelpers.emptyVersion)) AndAlso (Not version Is thisName.Version)) Then
                Return False
            End If
            Dim cultureInfo As CultureInfo = thatName.CultureInfo
            If ((Not cultureInfo Is Nothing) AndAlso Not cultureInfo.Equals(CultureInfo.InvariantCulture)) Then
                Dim parent As CultureInfo = thisName.CultureInfo
                If (Not parent Is Nothing) Then
                    Do
                        If cultureInfo.Equals(parent) Then
                            goto Label_0096
                        End If
                        parent = parent.Parent
                    Loop While Not parent.Equals(CultureInfo.InvariantCulture)
                End If
                Return False
            End If
        Label_0096:
            buffer = thatName.GetPublicKeyToken
            If ((Not buffer Is Nothing) AndAlso (buffer.Length <> 0)) Then
                Dim publicKeyToken As Byte() = thisName.GetPublicKeyToken
                If (publicKeyToken Is Nothing) Then
                    Return False
                End If
                If (buffer.Length <> publicKeyToken.Length) Then
                    Return False
                End If
                Dim i As Integer
                For i = 0 To buffer.Length - 1
                    If (buffer(i) <> publicKeyToken(i)) Then
                        Return False
                    End If
                Next i
            End If
            Return True
        End Function

        Friend Shared Function AssemblyNameEquals(ByVal thisName As AssemblyName, ByVal thatName As String) As Boolean
            If ((thisName Is Nothing) OrElse String.IsNullOrEmpty(thisName.Name)) Then
                Return False
            End If
            If String.IsNullOrEmpty(thatName) Then
                Return False
            End If
            Dim strArray As String() = thatName.Split(New Char() { ","c })
            If (strArray.Length = 0) Then
                Return False
            End If
            If Not strArray(0).Trim.Equals(thisName.Name) Then
                Return False
            End If
            If (strArray.Length = 1) Then
                Return True
            End If
            Dim version As Version = Nothing
            Dim info As CultureInfo = Nothing
            Dim buffer As Byte() = Nothing
            Dim i As Integer
            For i = 1 To strArray.Length - 1
                Dim str3 As String
                Dim index As Integer = strArray(i).IndexOf("="c)
                If (index <> -1) Then
                    Dim str4 As String
                    Dim str2 As String = strArray(i).Substring(0, index).Trim.ToLowerInvariant
                    str3 = strArray(i).Substring((index + 1)).Trim.ToLowerInvariant
                    If (Not String.IsNullOrEmpty(str3) AndAlso (Not str4 = str2 Is Nothing)) Then
                        If Not (str4 = "version") Then
                            If (str4 = "culture") Then
                                goto Label_00FC
                            End If
                            If (str4 = "publickeytoken") Then
                                goto Label_0115
                            End If
                        Else
                            version = New Version(str3)
                        End If
                    End If
                End If
                [Continue] For
            Label_00FC:
                If Not String.Equals(str3, "neutral", StringComparison.OrdinalIgnoreCase) Then
                    info = New CultureInfo(str3)
                End If
                [Continue] For
            Label_0115:
                If Not String.Equals(str3, "null", StringComparison.OrdinalIgnoreCase) Then
                    buffer = New Byte((str3.Length / 2)  - 1) {}
                    Dim j As Integer
                    For j = 0 To buffer.Length - 1
                        buffer(j) = Byte.Parse(str3.Substring((j * 2), 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture)
                    Next j
                End If
            Next i
            If (((Not version Is Nothing) AndAlso (Not version Is ParseHelpers.emptyVersion)) AndAlso (Not version Is thisName.Version)) Then
                Return False
            End If
            If ((Not info Is Nothing) AndAlso Not info.Equals(CultureInfo.InvariantCulture)) Then
                Dim cultureInfo As CultureInfo = thisName.CultureInfo
                If (Not cultureInfo Is Nothing) Then
                    Do
                        If info.Equals(cultureInfo) Then
                            goto Label_01DE
                        End If
                        cultureInfo = cultureInfo.Parent
                    Loop While Not cultureInfo.Equals(CultureInfo.InvariantCulture)
                End If
                Return False
            End If
        Label_01DE:
            If ((Not buffer Is Nothing) AndAlso (buffer.Length <> 0)) Then
                Dim publicKeyToken As Byte() = thisName.GetPublicKeyToken
                If (publicKeyToken Is Nothing) Then
                    Return False
                End If
                If (buffer.Length <> publicKeyToken.Length) Then
                    Return False
                End If
                Dim k As Integer
                For k = 0 To buffer.Length - 1
                    If (buffer(k) <> publicKeyToken(k)) Then
                        Return False
                    End If
                Next k
            End If
            Return True
        End Function

        Friend Shared Function FormatType(ByVal type As String, ByVal language As SupportedLanguages) As String
            Dim str As String = String.Empty
            Dim parameters As String() = Nothing
            Dim typeName As String = String.Empty
            Dim elemantDecorator As String = String.Empty
            If ParseHelpers.ParseTypeName(type, ParseTypeNameLanguage.NetFramework, typeName, parameters, elemantDecorator) Then
                If (elemantDecorator.Length > 0) Then
                    If (language = SupportedLanguages.VB) Then
                        elemantDecorator = elemantDecorator.Replace("["c, "("c).Replace("]"c, ")"c)
                    End If
                    Return (ParseHelpers.FormatType(typeName, language) & elemantDecorator)
                End If
                If ((Not parameters Is Nothing) AndAlso (parameters.Length > 0)) Then
                    str = ParseHelpers.FormatType(typeName, language)
                    If (language = SupportedLanguages.CSharp) Then
                        str = (str & "<"c)
                    Else
                        str = (str & "("c)
                    End If
                    Dim flag As Boolean = True
                    Dim str4 As String
                    For Each str4 In parameters
                        If Not flag Then
                            str = (str & ", ")
                        Else
                            If (language = SupportedLanguages.VB) Then
                                str = (str & "Of ")
                            End If
                            flag = False
                        End If
                        str = (str & ParseHelpers.FormatType(str4, language))
                    Next
                    If (language = SupportedLanguages.CSharp) Then
                        Return (str & ">"c)
                    End If
                    Return (str & ")"c)
                End If
                str = typeName.Replace("+"c, "."c)
                Dim index As Integer = str.IndexOf("`"c)
                If (index <> -1) Then
                    str = str.Substring(0, index)
                End If
                index = str.IndexOf(","c)
                If (index <> -1) Then
                    str = str.Substring(0, index)
                End If
            End If
            Return str
        End Function

        Friend Shared Function FormatType(ByVal type As Type, ByVal language As SupportedLanguages) As String
            Dim fullName As String = String.Empty
            If type.IsArray Then
                fullName = ParseHelpers.FormatType(type.GetElementType, language)
                If (language = SupportedLanguages.CSharp) Then
                    fullName = (fullName & "["c)
                Else
                    fullName = (fullName & "("c)
                End If
                fullName = (fullName & New String(","c, (type.GetArrayRank - 1)))
                If (language = SupportedLanguages.CSharp) Then
                    Return (fullName & "]"c)
                End If
                Return (fullName & ")"c)
            End If
            fullName = type.FullName
            Dim index As Integer = fullName.IndexOf("`"c)
            If (index <> -1) Then
                fullName = fullName.Substring(0, index)
            End If
            fullName = fullName.Replace("+"c, "."c)
            If (Not type.ContainsGenericParameters AndAlso Not type.IsGenericType) Then
                Return fullName
            End If
            Dim genericArguments As Type() = type.GetGenericArguments
            If (language = SupportedLanguages.CSharp) Then
                fullName = (fullName & "<"c)
            Else
                fullName = (fullName & "("c)
            End If
            Dim flag As Boolean = True
            Dim type2 As Type
            For Each type2 In genericArguments
                If Not flag Then
                    fullName = (fullName & ", ")
                Else
                    If (language = SupportedLanguages.VB) Then
                        fullName = (fullName & "Of ")
                    End If
                    flag = False
                End If
                fullName = (fullName & ParseHelpers.FormatType(type2, language))
            Next
            If (language = SupportedLanguages.CSharp) Then
                Return (fullName & ">"c)
            End If
            Return (fullName & ")"c)
        End Function

        Friend Shared Function ParseTypeName(ByVal typeProvider As ITypeProvider, ByVal language As SupportedLanguages, ByVal typeName As String) As Type
            Dim type As Type = Nothing
            type = typeProvider.GetType(typeName, False)
            If (type Is Nothing) Then
                Dim str As String = String.Empty
                Dim elemantDecorator As String = String.Empty
                Dim parameters As String() = Nothing
                If ParseHelpers.ParseTypeName(typeName, If((language = SupportedLanguages.CSharp), ParseTypeNameLanguage.CSharp, ParseTypeNameLanguage.VB), str, parameters, elemantDecorator) Then
                    type = typeProvider.GetType((str & elemantDecorator), False)
                End If
            End If
            Return type
        End Function

        Friend Shared Function ParseTypeName(ByVal inputTypeName As String, ByVal parseTypeNameLanguage As ParseTypeNameLanguage, <Out> ByRef typeName As String, <Out> ByRef parameters As String(), <Out> ByRef elemantDecorator As String) As Boolean
            typeName = String.Empty
            parameters = Nothing
            elemantDecorator = String.Empty
            If (parseTypeNameLanguage = ParseTypeNameLanguage.VB) Then
                inputTypeName = inputTypeName.Replace("("c, "["c).Replace(")"c, "]"c)
            ElseIf (parseTypeNameLanguage = ParseTypeNameLanguage.CSharp) Then
                inputTypeName = inputTypeName.Replace("<"c, "["c).Replace(">"c, "]"c)
            End If
            Dim length As Integer = inputTypeName.LastIndexOfAny(New Char() { "]"c, "&"c, "*"c })
            If (length = -1) Then
                typeName = inputTypeName
            ElseIf (inputTypeName.Chars(length) = "]"c) Then
                Dim num2 As Integer = length
                Dim num3 As Integer = 1
                Do While ((num2 > 0) AndAlso (num3 > 0))
                    num2 -= 1
                    If (inputTypeName.Chars(num2) = "]"c) Then
                        num3 += 1
                    ElseIf (inputTypeName.Chars(num2) = "["c) Then
                        num3 -= 1
                    End If
                Loop
                If (num3 <> 0) Then
                    Return False
                End If
                typeName = (inputTypeName.Substring(0, num2) & inputTypeName.Substring((length + 1)))
                Dim str As String = inputTypeName.Substring((num2 + 1), ((length - num2) - 1)).Trim
                If ((str = String.Empty) OrElse (str.TrimStart(New Char(0  - 1) {}).Chars(0) = ","c)) Then
                    elemantDecorator = ("[" & str & "]")
                Else
                    Dim num4 As Integer = 0
                    Dim chArray As Char() = str.ToCharArray
                    Dim i As Integer
                    For i = 0 To chArray.Length - 1
                        If (chArray(i) = "["c) Then
                            num4 += 1
                        ElseIf (chArray(i) = "]"c) Then
                            num4 -= 1
                        ElseIf ((chArray(i) = ","c) AndAlso (num4 = 0)) Then
                            chArray(i) = "$"c
                        End If
                    Next i
                    parameters = New String(chArray).Split(New Char() { "$"c })
                    Dim j As Integer
                    For j = 0 To parameters.Length - 1
                        parameters(j) = parameters(j).Trim
                        If (parameters(j).Chars(0) = "["c) Then
                            parameters(j) = parameters(j).Substring(1, (parameters(j).Length - 2))
                        End If
                        If ((parseTypeNameLanguage = ParseTypeNameLanguage.VB) AndAlso parameters(j).StartsWith("Of ", StringComparison.OrdinalIgnoreCase)) Then
                            parameters(j) = parameters(j).Substring(3).TrimStart(New Char(0  - 1) {})
                        End If
                    Next j
                End If
            Else
                typeName = (inputTypeName.Substring(0, length) & inputTypeName.Substring((length + 1)))
                elemantDecorator = inputTypeName.Substring(length, 1)
            End If
            If ((parseTypeNameLanguage = ParseTypeNameLanguage.CSharp) AndAlso ParseHelpers.CSKeywords.Contains(typeName)) Then
                typeName = ParseHelpers.DotNetKeywords(ParseHelpers.CSKeywords.IndexOf(typeName))
            ElseIf ((parseTypeNameLanguage = ParseTypeNameLanguage.VB) AndAlso ParseHelpers.VBKeywords.Contains(typeName)) Then
                typeName = ParseHelpers.DotNetKeywords(ParseHelpers.VBKeywords.IndexOf(typeName))
            End If
            Return True
        End Function


        ' Fields
        Private Shared ReadOnly CSKeywords As ArrayList = New ArrayList(New String() { "int", "string", "bool", "object", "void", "float", "double", "char", "Date", "long", "byte", "short", "Single", "double", "decimal", "uint", "ulong", "sbyte", "ushort" })
        Private Const CultureTag As String = "culture"
        Private Shared ReadOnly DotNetKeywords As String() = New String() { "System.Int32", "System.String", "System.Boolean", "System.Object", "System.Void", "System.Single", "System.Double", "System.Char", "System.DateTime", "System.Int64", "System.Byte", "System.Int16", "System.Single", "System.Double", "System.Decimal", "System.UInt32", "System.UInt64", "System.SByte", "System.UInt16" }
        Private Shared ReadOnly emptyVersion As Version = New Version(0, 0, 0, 0)
        Private Const PublicKeyTokenTag As String = "publickeytoken"
        Private Shared ReadOnly VBKeywords As ArrayList = New ArrayList(New String() { "Integer", "String", "Boolean", "Object", "Void", "Single", "Double", "Char", "DateTime", "Long", "Byte", "Short", "Single", "Double", "Decimal", "UInteger", "ULong", "SByte", "UShort" })
        Private Const VersionTag As String = "version"

        ' Nested Types
        Friend Enum ParseTypeNameLanguage
            ' Fields
            CSharp = 1
            NetFramework = 2
            VB = 0
        End Enum
    End Class
End Namespace

